"""
AI Prompts Management Views
AI提示词管理API视图
"""
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.shortcuts import get_object_or_404
from django.utils import timezone
import json
import logging

from .prompts import prompt_manager, PromptType, Subject, DifficultyLevel, PromptTemplate
from .ai_config import AI_USE_NEW_PROMPT_SYSTEM

logger = logging.getLogger(__name__)

class PromptTemplateViewSet(viewsets.ViewSet):
    """提示词模板管理视图集"""
    permission_classes = [IsAuthenticated]

    @swagger_auto_schema(
        operation_summary="列出所有提示词模板",
        operation_description="获取系统中所有可用的提示词模板列表",
        responses={
            200: openapi.Response(
                description="成功获取模板列表",
                schema=openapi.Schema(
                    type=openapi.TYPE_ARRAY,
                    items=openapi.Schema(
                        type=openapi.TYPE_OBJECT,
                        properties={
                            'id': openapi.Schema(type=openapi.TYPE_STRING),
                            'name': openapi.Schema(type=openapi.TYPE_STRING),
                            'description': openapi.Schema(type=openapi.TYPE_STRING),
                            'type': openapi.Schema(type=openapi.TYPE_STRING),
                            'subject': openapi.Schema(type=openapi.TYPE_STRING),
                            'difficulty': openapi.Schema(type=openapi.TYPE_STRING),
                            'version': openapi.Schema(type=openapi.TYPE_STRING),
                            'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN)
                        }
                    )
                )
            )
        }
    )
    def list(self, request):
        """列出所有提示词模板"""
        try:
            if not AI_USE_NEW_PROMPT_SYSTEM:
                return Response({
                    'error': '新提示词系统未启用',
                    'message': '请在配置中启用 AI_USE_NEW_PROMPT_SYSTEM'
                }, status=status.HTTP_503_SERVICE_UNAVAILABLE)

            templates = prompt_manager.list_templates()
            return Response({
                'success': True,
                'data': templates,
                'total': len(templates)
            })
        except Exception as e:
            logger.error(f"获取提示词模板列表失败: {str(e)}")
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @swagger_auto_schema(
        operation_summary="获取单个提示词模板",
        operation_description="根据ID获取指定的提示词模板详情",
        manual_parameters=[
            openapi.Parameter(
                'template_id',
                openapi.IN_PATH,
                description="模板ID",
                type=openapi.TYPE_STRING,
                required=True
            )
        ],
        responses={
            200: openapi.Response(description="成功获取模板详情"),
            404: openapi.Response(description="模板不存在")
        }
    )
    def retrieve(self, request, template_id=None):
        """获取单个提示词模板"""
        try:
            if not AI_USE_NEW_PROMPT_SYSTEM:
                return Response({
                    'error': '新提示词系统未启用'
                }, status=status.HTTP_503_SERVICE_UNAVAILABLE)

            template = prompt_manager.get_template(template_id)
            if not template:
                return Response({
                    'success': False,
                    'error': '模板不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            return Response({
                'success': True,
                'data': {
                    'id': template.id,
                    'name': template.name,
                    'description': template.description,
                    'type': template.type.value,
                    'subject': template.subject.value if template.subject else None,
                    'difficulty': template.difficulty.value if template.difficulty else None,
                    'template': template.template,
                    'variables': template.variables,
                    'examples': template.examples,
                    'version': template.version,
                    'is_active': template.is_active,
                    'metadata': template.metadata
                }
            })
        except Exception as e:
            logger.error(f"获取提示词模板失败: {str(e)}")
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @swagger_auto_schema(
        operation_summary="渲染提示词模板",
        operation_description="使用提供的变量渲染提示词模板",
        manual_parameters=[
            openapi.Parameter(
                'template_id',
                openapi.IN_PATH,
                description="模板ID",
                type=openapi.TYPE_STRING,
                required=True
            )
        ],
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'variables': openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    description="模板变量键值对",
                    example={
                        'topic': '一元二次方程',
                        'difficulty': 'medium',
                        'count': 5
                    }
                )
            }
        ),
        responses={
            200: openapi.Response(description="成功渲染模板"),
            400: openapi.Response(description="变量缺失或格式错误"),
            404: openapi.Response(description="模板不存在")
        }
    )
    @action(detail=True, methods=['post'])
    def render(self, request, template_id=None):
        """渲染提示词模板"""
        try:
            if not AI_USE_NEW_PROMPT_SYSTEM:
                return Response({
                    'error': '新提示词系统未启用'
                }, status=status.HTTP_503_SERVICE_UNAVAILABLE)

            template = prompt_manager.get_template(template_id)
            if not template:
                return Response({
                    'success': False,
                    'error': '模板不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            variables = request.data.get('variables', {})
            if not variables:
                return Response({
                    'success': False,
                    'error': '请提供模板变量'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 渲染模板
            rendered_prompt = prompt_manager.render_template(template_id, variables)

            return Response({
                'success': True,
                'data': {
                    'template_id': template_id,
                    'rendered_prompt': rendered_prompt,
                    'variables_used': list(variables.keys()),
                    'rendered_at': timezone.now().isoformat()
                }
            })
        except ValueError as e:
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"渲染提示词模板失败: {str(e)}")
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @swagger_auto_schema(
        operation_summary="按类型获取提示词模板",
        operation_description="根据提示词类型获取相关模板",
        manual_parameters=[
            openapi.Parameter(
                'prompt_type',
                openapi.IN_PATH,
                description="提示词类型",
                type=openapi.TYPE_STRING,
                required=True,
                enum=[t.value for t in PromptType]
            )
        ],
        responses={
            200: openapi.Response(description="成功获取模板列表")
        }
    )
    @action(detail=False, methods=['get'], url_path='type/(?P<prompt_type>[^/.]+)')
    def by_type(self, request, prompt_type=None):
        """按类型获取提示词模板"""
        try:
            if not AI_USE_NEW_PROMPT_SYSTEM:
                return Response({
                    'error': '新提示词系统未启用'
                }, status=status.HTTP_503_SERVICE_UNAVAILABLE)

            # 验证提示词类型
            try:
                prompt_type_enum = PromptType(prompt_type)
            except ValueError:
                return Response({
                    'success': False,
                    'error': f'无效的提示词类型: {prompt_type}',
                    'valid_types': [t.value for t in PromptType]
                }, status=status.HTTP_400_BAD_REQUEST)

            templates = prompt_manager.get_templates_by_type(prompt_type_enum)
            result = [
                {
                    'id': t.id,
                    'name': t.name,
                    'description': t.description,
                    'subject': t.subject.value if t.subject else None,
                    'difficulty': t.difficulty.value if t.difficulty else None,
                    'version': t.version
                }
                for t in templates
            ]

            return Response({
                'success': True,
                'data': result,
                'total': len(result),
                'prompt_type': prompt_type
            })
        except Exception as e:
            logger.error(f"按类型获取提示词模板失败: {str(e)}")
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @swagger_auto_schema(
        operation_summary="按学科获取提示词模板",
        operation_description="根据学科获取相关模板",
        manual_parameters=[
            openapi.Parameter(
                'subject',
                openapi.IN_PATH,
                description="学科",
                type=openapi.TYPE_STRING,
                required=True,
                enum=[s.value for s in Subject]
            )
        ],
        responses={
            200: openapi.Response(description="成功获取模板列表")
        }
    )
    @action(detail=False, methods=['get'], url_path='subject/(?P<subject>[^/.]+)')
    def by_subject(self, request, subject=None):
        """按学科获取提示词模板"""
        try:
            if not AI_USE_NEW_PROMPT_SYSTEM:
                return Response({
                    'error': '新提示词系统未启用'
                }, status=status.HTTP_503_SERVICE_UNAVAILABLE)

            # 验证学科
            try:
                subject_enum = Subject(subject)
            except ValueError:
                return Response({
                    'success': False,
                    'error': f'无效的学科: {subject}',
                    'valid_subjects': [s.value for s in Subject]
                }, status=status.HTTP_400_BAD_REQUEST)

            templates = prompt_manager.get_templates_by_subject(subject_enum)
            result = [
                {
                    'id': t.id,
                    'name': t.name,
                    'description': t.description,
                    'type': t.type.value,
                    'difficulty': t.difficulty.value if t.difficulty else None,
                    'version': t.version
                }
                for t in templates
            ]

            return Response({
                'success': True,
                'data': result,
                'total': len(result),
                'subject': subject
            })
        except Exception as e:
            logger.error(f"按学科获取提示词模板失败: {str(e)}")
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @swagger_auto_schema(
        operation_summary="获取提示词元数据",
        operation_description="获取提示词系统的元数据信息，包括支持的类型、学科等",
        responses={
            200: openapi.Response(
                description="成功获取元数据",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'prompt_types': openapi.Schema(
                            type=openapi.TYPE_ARRAY,
                            items=openapi.Schema(type=openapi.TYPE_STRING)
                        ),
                        'subjects': openapi.Schema(
                            type=openapi.TYPE_ARRAY,
                            items=openapi.Schema(type=openapi.TYPE_STRING)
                        ),
                        'difficulty_levels': openapi.Schema(
                            type=openapi.TYPE_ARRAY,
                            items=openapi.Schema(type=openapi.TYPE_STRING)
                        ),
                        'system_enabled': openapi.Schema(type=openapi.TYPE_BOOLEAN)
                    }
                )
            )
        }
    )
    @action(detail=False, methods=['get'])
    def metadata(self, request):
        """获取提示词元数据"""
        try:
            return Response({
                'success': True,
                'data': {
                    'prompt_types': [t.value for t in PromptType],
                    'subjects': [s.value for s in Subject],
                    'difficulty_levels': [d.value for d in DifficultyLevel],
                    'system_enabled': AI_USE_NEW_PROMPT_SYSTEM,
                    'total_templates': len(prompt_manager.templates)
                }
            })
        except Exception as e:
            logger.error(f"获取提示词元数据失败: {str(e)}")
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @swagger_auto_schema(
        operation_summary="测试提示词模板",
        operation_description="使用示例数据测试提示词模板的效果",
        manual_parameters=[
            openapi.Parameter(
                'template_id',
                openapi.IN_PATH,
                description="模板ID",
                type=openapi.TYPE_STRING,
                required=True
            )
        ],
        responses={
            200: openapi.Response(description="成功测试模板"),
            404: openapi.Response(description="模板不存在")
        }
    )
    @action(detail=True, methods=['get'])
    def test(self, request, template_id=None):
        """测试提示词模板"""
        try:
            if not AI_USE_NEW_PROMPT_SYSTEM:
                return Response({
                    'error': '新提示词系统未启用'
                }, status=status.HTTP_503_SERVICE_UNAVAILABLE)

            template = prompt_manager.get_template(template_id)
            if not template:
                return Response({
                    'success': False,
                    'error': '模板不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            if not template.examples:
                return Response({
                    'success': False,
                    'error': '该模板没有测试示例'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 使用第一个示例进行测试
            example = template.examples[0]
            rendered_prompt = prompt_manager.render_template(template_id, example)

            return Response({
                'success': True,
                'data': {
                    'template_id': template_id,
                    'example_variables': example,
                    'rendered_prompt': rendered_prompt,
                    'template_length': len(rendered_prompt),
                    'tested_at': timezone.now().isoformat()
                }
            })
        except Exception as e:
            logger.error(f"测试提示词模板失败: {str(e)}")
            return Response({
                'success': False,
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)